<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<link rel="Stylesheet" type="text/css" href="doc.css" />
<title>Creating Transactions</title>
</head>
<body>
<h1><a name="top">Creating Transactions</a></h1>
<p>
</p>

<p>
A <a href="../javadoc/org/eclipse/emf/transaction/Transaction.html"><em class="CodeName">Transaction</em></a>
is a discrete unit of work in a <em class="CodeName">ResourceSet</em>.  This work may be
reading and writing the resource set contents or simply reading.  Transactions provide
model integrity guarantees:
</p>
<ul>
  <li>isolation of concurrent threads to prevent data corruption</li>
  <li>validation of changes on commit, rolling back (undoing those changes) automatically
      when data integrity is violated</li>
  <li>automatic execution of <a href="triggers.html">triggers</a> on commit, to proactively
      maintain data integrity</li>
</ul>
<p class="Note">
The EMF Transaction API is not a concurrent transactional environment.  Transactions on
multiple threads execute in strictly serial order.
</p>
<p>
<em class="CodeName">Transaction</em>s are first-class object, maintaining all of the state
required to ensure integrity, including recorded changes (for roll-back) and knowledge of
which thread owns it.  Most clients will never have to interact directly with the transaction
object, but only with the editing domain. 
</p>

<h2>Reading the Contents of the Resource Set</h2>

<p>
The default code generated by EMF is not thread-safe, even for reading.  Lazy initialization
is not protected by synchronization; multiple concurrent threads could all resolve the same
proxy or create the same <em class="CodeName">EList</em> by reading the value of a
previously uninitialized feature, resulting in multiple copies of the same data and
inconsistent read and/or update experiences.
</p>

<blockquote>
	<img src="images/read.png" alt="Transactional Reading API"/><br/>
	<font size="-2">[<a href="images/read.svg">as SVG</a>]</font>
</blockquote>

<p>
The EMF Transaction API provides a solution in the form of read-only transactions.  A
read-only transaction gives a thread exclusive access to the resource set of a transactional
editing domain for the purpose of reading (writing is not permitted).  Other threads that
wish to read will block in the attempt to start read-only transactions until the reading
thread relinquishes its transaction, either by committing it or by
<a href="sharing.html">other means</a>.
</p><p>
To perform read the contents of a resource set in a read-only transaction, encapsulate the
read operation in a <em class="CodeName">Runnable</em> and pass it to the
<a href="../javadoc/org/eclipse/emf/transaction/TransactionalEditingDomain.html#runExclusive(java.lang.Runnable)"><em class="CodeName">TransactionalEditingDomain.runExclusive()</em></a>
method.  The editing waits until it can start a read-only transaction on the current thread,
then runs the runnable in that context.
</p><p>
This API works with plain <em class="CodeName">Runnable</em>s, but when used with a
<a href="../javadoc/org/eclipse/emf/transaction/RunnableWithResult.html"><em class="CodeName">RunnableWithResult</em></a>,
the <em class="CodeName">runExclusive()</em> method returns the result of the runnable.
This is convenient for small read operations that simply need to find an object or compute
some value and return it.  The <em class="CodeName">RunnableWithResult.Impl</em> inner class
is a convenient superclass for these read operations.
</p>
<pre class="Code">
TransactionalEditingDomain domain;

// search for the Richmond branch of the library system
Library richmond = (Library) domain.<b>runExclusive</b>(new <b>RunnableWithResult.Impl</b>() {
    public void run() {
        TreeIterator iter = resource.getAllContents();
        
        while (iter.hasNext()) {
            Object next = iter.next();
            
            if (next instanceof Library) {
                Library lib = (Library) next;
                
                if ("Richmond Branch".equals(lib.getName()) {
                    <b>setResult</b>(lib);  // found it
                    break;
                }
            } else {
                iter.prune();
            }
        }
    }});
    
System.out.println("Found: " + richmond);
</pre>
<p>
A <em class="CodeName">RunnableWithResult</em> also has a status, which indicates any
problems in committing the transaction.  Ordinarily, read-only transactions can never be
rolled back because there are no changes to validate, but it can happen in rare cases of
failure of concurrency controls.
</p>

<h2>Writing the Contents of the Resource Set</h2>

<p>
The other kind of transaction is a read/write transaction, in which a client thread makes
changes to the contents of a resource set.  As is recommended in the base
<em class="CodeName">EditingDomain</em> of the <em class="UILabel">EMF.Edit</em> framework,
all changes to data managed by a transactional editing domain are performed by
<em class="CodeName">Command</em>s.
</p>

<blockquote>
	<img src="images/commands.png" alt="Transactional Commands API"/><br/>
	<font size="-2">[<a href="images/commands.svg">as SVG</a>]</font>
</blockquote>

<p>
As an <em class="CodeName">EditingDomain</em> has its <em class="CodeName">CommandStack</em>,
so does a <em class="CodeName">TransactionalEditingDomain</em> have its
<a href="../javadoc/org/eclipse/emf/transaction/TransactionalCommandStack.html"><em class="CodeName">TransactionalCommandStack</em></a>.
All EMF <em class="CodeName">Command</em>s executed on the transactional command stack are
provided with read/write transactions in which to make their changes, first waiting if
necessary for other reading or writing threads to commit or to relinquish their transactions
by <a href="sharing.html">other means</a>.
</p>
<pre class="Code">
Library richmond = getLibrary("Richmond Branch");  // this would use a read-only transaction
TransactionalEditingDomain domain = getEditingDomain();

CommandStack stack = domain.<b>getCommandStack</b>();

// execute some change, just as in any EMF.Edit application
Command cmd = domain.createCommand(
       SetCommand.class,
       new CommandParameter(richmond, EXTLibraryPackage.Literals.LIBRARY__ADDRESS, "5600 Perth St."));

stack.<b>execute</b>(cmd);
</pre>
<p>
In the transactional environment, data integrity mechanisms such as validation can cause a
read/write transaction to roll back if it would violate integrity constraints.  However, the
basic command-stack API assumes that commands cannot fail, so it provides no feedback when
rollback occurs.  The <em class="CodeName">TransactionalCommandStack</em> provides an
alternative API that throws
<a href="../javadoc/org/eclipse/emf/transaction/RollbackException.html"><em class="CodeName">RollbackException</em></a>
when the transaction is rolled back or <em class="CodeName">InterruptedException</em> if
the transaction cannot even begin because the current thread is interrupted while waiting
for the transaction to start.  Modifying the example, above:
</p>
<pre class="Code">
Library richmond = getLibrary("Richmond Branch");  // this would use a read-only transaction
TransactionalEditingDomain domain = getEditingDomain();

<b>TransactionalCommandStack</b> tstack = (TransactionalCommandStack) domain.<b>getCommandStack</b>();

Command cmd = domain.createCommand(
       SetCommand.class,
       new CommandParameter(richmond, EXTLibraryPackage.Literals.LIBRARY__ADDRESS, "5600 Perth St."));

try {
    tstack.<b>execute</b>(cmd, Collections.EMPTY_MAP);
} catch (InterruptedException e) {
    MessageDialog.openError(shell, "Command Failed",
            "Interrupted while waiting for a read/write transaction.");
} catch (<b>RollbackException</b> e) {
    ErrorDialog.openError(shell, "Command Failed", "Transaction rolled back",
            e.<b>getStatus</b>());
}
</pre>
<p>
The overloaded <em class="CodeName">execute()</em> method is distinguished by an
<em class="CodeName">options</em> map that supplies transaction options, described
<a href="options.html">elsewhere</a>.  The <em class="CodeName">RollbackException</em>,
should it occur, provides an <em class="CodeName">IStatus</em> carrying a human-readable
reason for the rollback.
</p>

<h2>Using RecordingCommands</h2>

<p>
The transaction in which a <em class="CodeName">Command</em> is executed records all of the
changes that the command performs in case it needs to roll back, undoing those changes.
The <a href="../javadoc/org/eclipse/emf/transaction/RecordingCommand.html"><em class="CodeName">RecordingCommand</em></a>
class is a convenient command implementation that takes advantage of this recorded information
to provide automatic undo/redo support, without the necessity of composing complex
nested command structures.  This has the additional benefit that the command can determine
what changes are required at the time of execution, rather than <em>a priori</em>.
</p>
<pre class="Code">
TransactionalCommandStack stack;

stack.execute(new <b>RecordingCommand</b>() {
    protected void doExecute() {
        Iterator iter = resource.getAllContents();
        while (iter.hasNext()) {  // changes are determined on-the-fly
            Object next = iter.next();
            if (next instanceof Library) {
                ((Library) next).getBooks().add(
                        EXTLibraryFactory.eINSTANCE.createBook());
            }
        }
    }}, Collections.EMPTY_MAP);
</pre>
<p>
The <em class="CodeName">RecordingCommand</em> requires only that subclasses implement the
abstract <em class="CodeName">doExecute()</em> method.  The rest of the
<em class="CodeName">Command</em> API is implemented automatically, including
<em class="CodeName">undo()</em> and <em class="CodeName">redo()</em>.
</p><p>
Depending on potential data integrity violations, it is not absolutely certain that, as
is assumed by the <em class="UILabel">EMF.Edit</em> framework, any command that was
successfully undone can be redone.  In consequence, the transaction API defines a
<a href="../javadoc/org/eclipse/emf/transaction/util/ConditionalRedoCommand.html"><em class="CodeName">ConditionalRedoCommand</em></a>
interface with a <em class="CodeName">canRedo()</em> query.  All of the commands defined
by the transaction API implement this interface.
</p>

<hr/>

<p>
<a href="https://www.eclipse.org/legal/epl-2.0/">Copyright (c) 2006, 2007 IBM Corporation and others.</a>
</p>
</body>
</html>
